#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
// 堆栈应用，应用堆栈实现后缀表达式求值

/*将中缀表达式转化为后缀表达式

从头到尾读取中缀表达式的每个对象，对不同对象按不同的情况处理
1.运算数：直接输出
2.左括号：入栈
3.右括号：将栈顶的运算符弹出并输出，知道遇到左括号（左括号只弹出，不输出）
4.运算符：
   若优先级大于栈顶运算符时，就直接入栈
   若优先级小于或等于栈顶运算符时，将栈顶运算符弹出并输出；再比较新的栈顶运算符，直到该运算符大于栈顶运算符优先级为止
5.若各对象处理完毕，则把堆栈中存留的运算符一并输出*/
#define MAXOP 100    // 操作数序列的最大长度
#define INFINITY 1e9 // 无穷
typedef double ElementType;

typedef enum
{ // 类型依次对应运算数，运算符，字符串结尾
    num,
    opr,
    end
} Type; // 枚举类型是一个集合，集合中的元素是一些命名的整形常量。第一个枚举成员的默认值为整形的0，后续枚举成员的值在前一个成员上+1。

// 接下来我们来创建栈并且构建栈的基本操作push和pop
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode
{
    ElementType *Data;
    Position Top;
    int MaxSize;
};
typedef PtrToSNode Stack;

// 创建栈
Stack CreateStack(int MaxSize)
{
    Stack S = (Stack)malloc(sizeof(struct SNode));
    S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
    S->Top = -1;
    S->MaxSize = MaxSize;
    return S;
}
// 入栈操作
void Push(Stack S, ElementType X)
{
    if (S->Top == S->MaxSize - 1)
    {
        printf("栈满");
        return;
    }
    else
    {
        S->Data[++S->Top] = X;
        return;
    }
}
// 出栈操作
ElementType Pop(Stack S)
{
    if (S->Top == -1)
    {
        printf("栈空");
        return -10000;
    }
    else
    {
        return S->Data[S->Top--];
    }
}

// 接下来我们开始创建读取函数
Type Getop(char *Expr, int *start, char *str)
{
    // 从start开始读入下一个对象（操作数或运算符），并保存在字符串str中
    int i = 0;

    // 跳过表达式前的空格
    while ((str[0] = Expr[(*start)++]) == ' ')
        ;

    while (str[i] != ' ' && str[i] != '\0')
    {
        str[++i] = Expr[(*start)++];
    }
    if (str[i] == '\0')
        (*start)--;
    str[i] = '\0';

    if (i == 0)
        return end;
    else if (isdigit(str[0]) || isdigit(str[1]))
        return num;
    else
        return opr;
}

ElementType PostfixExp(char *Expr)
{
    Stack S;
    Type T;
    ElementType op1, op2;
    char str[MAXOP];
    int start = 0;

    // 申请一个新堆栈
    S = CreateStack(MAXOP);

    op1 = op2 = 0;
    while ((T = Getop(Expr, &start, str)) != end)
    {
        if (T == num)
        {
            Push(S, atof(str));
        }
        else
        {
            op2 = Pop(S);
            op1 = Pop(S);
            switch (str[0])
            {
            case '+':
                Push(S, op1 + op2);
                break;
            case '-':
                Push(S, op1 - op2);
                break;
            case '*':
                Push(S, op1 * op2);
                break;
            case '/':
                if (op2 != 0.0)
                    Push(S, op1 / op2);
                else
                {
                    printf("错误，除法分母为0");
                    op2 = INFINITY;
                }
                break;
            default:
                printf("错误：未知运算符%s\n", str);
                op2 = INFINITY;
                break;
            }
        }
        if (op2 >= INFINITY)
            break;
    }
    if (op2 < INFINITY)
        op2 = Pop(S);
    free(S);
    return op2;
}

int main()
{
    char Expr[MAXOP];
    ElementType f;

    gets(Expr);
    f = PostfixExp(Expr);
    if (f < INFINITY)
        printf("%.4f\n", f);
    else
        printf("表达式错误\n");

    return 0;
}
